<template>
  <div>
    <!-- Three.js 渲染容器 -->
    <div id="container" />
  </div>
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import Stats from 'three/examples/jsm/libs/stats.module.js'

export default {
  name: 'FactoryExample',
  data () {
    return {
      // Three.js 核心对象
      scene: null,          // 场景
      camera: null,         // 相机
      renderer: null,       // 渲染器
      labelRenderer: null,  // 标签渲染器（未使用）
      container: null,      // DOM 容器
      controls: null,       // 轨道控制器

      // 场景尺寸参数
      floor: { floorWidth: 500, floorLength: 500, depth: 1 }, // 地板尺寸
      wall: { wallWidth: 700, wallLength: 700, wallHeight: 20 }, // 墙壁尺寸（未使用）

      // 3D 模型对象
      agvModel: null,       // AGV小车模型
      boxModel: null,       // 箱子模型（手动创建）
      agvCopyModel: null,  // 复制的AGV模型
      boxCopyModel: null,  // 复制的箱子模型
      agvBoxModel: null,   // AGV和箱子的组合（未使用）

      // 模型位置参数
      agvPosition: { x: 0, y: 0, z: 0 },  // AGV初始位置
      boxPosition: { x: 0, y: 0, z: 0 },  // 箱子初始位置
      agvBoxPosition: { start: -120, end: 120 }, // 组合模型移动范围

      // 路径动画相关
      pathPoints: [],      // 路径点数组
      cameraCurve: null,   // 曲线路径（用于箱子移动）
      pathIndex: 0,        // 当前路径点索引

      // 性能监控（已注释）
      stats: null
    }
  },
  mounted () {
    this.initPage() // 页面加载后初始化
  },
  methods: {
    // 初始化场景
    initScene () {
      this.scene = new THREE.Scene()
      this.scene.background = new THREE.Color('#87CEEB') // 设置天空蓝背景
      // 坐标轴辅助（调试用，已注释）
      // const axesHelper = new THREE.AxesHelper(100)
      // axesHelper.position.set(0, 0, 10)
      // this.scene.add(axesHelper)
      // 性能监控（已注释）
      // this.stats = new Stats()
      // document.body.appendChild(this.stats.domElement)
    },

    // 初始化相机
    initCamera () {
      this.camera = new THREE.PerspectiveCamera(
        45, // 视野角度
        window.innerWidth / window.innerHeight, // 宽高比
        0.1, // 近裁剪面
        10000 // 远裁剪面
      )
      this.camera.position.set(0, 200, 200) // 相机位置
      this.camera.lookAt(0, 0, 0) // 看向原点
      this.camera.up.set(0, 0, 1) // 设置Z轴为上方（默认Y轴向上）
    },

    // 初始化光源
    initLight () {
      // 平行光1
      const directionalLight1 = new THREE.DirectionalLight(0xffffff, 1.5)
      directionalLight1.position.set(-300, -300, 600)
      this.scene.add(directionalLight1)
      // 平行光2
      const directionalLight2 = new THREE.DirectionalLight(0xffffff, 1.5)
      directionalLight2.position.set(600, 200, 600)
      this.scene.add(directionalLight2)
    },

    // 初始化地板
    initFloor () {
      const floorGeometry = new THREE.BoxGeometry(
        this.floor.floorLength,
        this.floor.floorWidth,
        this.floor.depth
      )
      const cubeMaterial = new THREE.MeshPhysicalMaterial({ color: '#CCCCCC' })
      const floor = new THREE.Mesh(floorGeometry, cubeMaterial)
      floor.position.set(0, 0, 0)
      this.scene.add(floor)
    },

    // 加载工厂模型
    initFactory () {
      const loader = new GLTFLoader()
      loader.load('/static/examples/product/make.glb', (gltf) => {
        gltf.scene.scale.set(10, 10, 10) // 缩放模型
        gltf.scene.position.set(0, 0, 18) // 位置调整
        gltf.scene.rotation.x = Math.PI / 2 // X轴旋转90度
        gltf.scene.rotation.y = Math.PI / 2 // Y轴旋转90度
        this.scene.add(gltf.scene)
      })
    },

    // 加载AGV小车模型
    initAgv () {
      const loader = new GLTFLoader()
      loader.load('/static/examples/product/agv.glb', (gltf) => {
        this.agvModel = gltf.scene
        this.agvModel.scale.set(10, 10, 10)
        this.agvModel.position.set(-10, -94, 3)
        this.agvModel.rotation.x = Math.PI / 2
        this.agvModel.rotation.y = Math.PI / 2
        this.agvModel.name = 'agv' // 设置名称便于查找
        this.scene.add(this.agvModel)
      })
    },

    // 初始化箱子模型和路径
    initBox () {
      // 加载箱子纹理
      const textureLoader = new THREE.TextureLoader()
      textureLoader.load('/static/examples/product/box.jpg', (texture) => {
        const box = new THREE.BoxGeometry(10, 10, 10) // 创建立方体
        const material = new THREE.MeshPhysicalMaterial({ map: texture }) // 使用纹理材质
        this.boxModel = new THREE.Mesh(box, material)
        this.boxModel.position.set(10, -94.5, 9)
        this.boxModel.name = 'box'
        this.scene.add(this.boxModel)
      })

      // 定义箱子移动路径
      const vectorList = []
      vectorList.push(new THREE.Vector3(10, -94, 13)) // 起点
      // 水平移动（X轴增加）
      for (let i = 0; i < 131; i++) {
        vectorList.push(new THREE.Vector3(10 + i, -94, 13))
      }
      // 斜向移动（X和Y同时变化）
      for (let i = 0; i < 20; i++) {
        vectorList.push(new THREE.Vector3(141 + i * 0.5, -93 + i * 0.5, 13))
      }
      // 垂直移动（Y轴增加）
      for (let i = 0; i < 84; i++) {
        vectorList.push(new THREE.Vector3(150, i - 84, 13))
      }
      vectorList.push(new THREE.Vector3(150, 0, 13)) // 终点

      // 控制台输出路径点（调试用）
      for (let i = 0; i < vectorList.length; i++) {
        console.log(vectorList[i].x + ',' + vectorList[i].y + ',' + vectorList[i].z)
      }

      // 创建平滑路径曲线
      this.cameraCurve = new THREE.CatmullRomCurve3(vectorList, false)
      this.pathPoints = this.cameraCurve.getPoints(1000) // 采样1000个点
    },

    // 初始化AGV和箱子的组合模型
    initAgvBox () {
      const loader = new GLTFLoader()
      loader.load('/static/examples/product/agv.glb', (gltf) => {
        this.agvCopyModel = gltf.scene
        this.agvCopyModel.scale.set(10, 10, 10)
        this.agvCopyModel.position.set(-120, 79, 3)
        this.agvCopyModel.rotation.x = Math.PI / 2
        this.agvCopyModel.rotation.y = Math.PI / 2
        this.agvCopyModel.name = 'agvCopy'

        // 创建组合对象
        const group = new THREE.Group()
        group.add(this.agvCopyModel)

        // 加载箱子模型
        loader.load('/static/examples/product/box.glb', (gltf) => {
          this.boxCopyModel = gltf.scene
          this.boxCopyModel.scale.set(10, 10, 10)
          this.boxCopyModel.position.set(-105, 76, 3)
          this.boxCopyModel.rotation.x = Math.PI / 2
          this.boxCopyModel.rotation.y = Math.PI / 2
          this.boxCopyModel.name = 'boxCopy'
          this.scene.add(this.boxCopyModel)
          group.add(this.boxCopyModel)
          group.name = 'agvBox'
          this.scene.add(group)
        })
      })
    },

    // 初始化渲染器
    initRenderer () {
      this.renderer = new THREE.WebGLRenderer({ antialias: true }) // 开启抗锯齿
      this.container = document.getElementById('container')
      this.renderer.setSize(this.container.clientWidth, this.container.clientHeight)
      this.renderer.setClearColor('#CCCCCC', 1.0) // 设置默认背景色
      this.container.appendChild(this.renderer.domElement)
    },

    // 初始化轨道控制器
    initControl () {
      this.controls = new OrbitControls(this.camera, this.renderer.domElement)
      this.controls.enableDamping = true // 启用阻尼（惯性效果）
      this.controls.maxPolarAngle = Math.PI / 2.2 // 限制垂直旋转角度
      this.controls.target = new THREE.Vector3(0, 0, 0) // 控制中心点
      this.camera.position.set(0, 200, 200) // 重置相机位置
      this.camera.lookAt(0, 0, 0) // 看向原点
    },

    // 动画循环
    initAnimate () {
      requestAnimationFrame(this.initAnimate) // 循环调用自身

      // 更新路径索引（循环播放）
      if (this.pathIndex === 999) {
        this.pathIndex = 0
      } else {
        this.pathIndex += 1
      }

      // 箱子沿路径移动
      if (this.boxModel && this.pathPoints.length > 0) {
        const beginPoint = this.pathPoints[this.pathIndex]
        this.boxModel.position.set(beginPoint.x, beginPoint.y, beginPoint.z)
        const endPoint = this.pathPoints[this.pathIndex + 1]
        this.boxModel.lookAt(endPoint) // 箱子朝向移动方向
      }

      // AGV组合模型水平移动（往返循环）
      for (let i = 0; i < this.scene.children.length; i++) {
        if (this.scene.children[i].name === 'agvBox') {
          this.scene.children[i].position.x += 0.2
          if (this.scene.children[i].position.x > 120) {
            this.scene.children[i].position.x = -80
          }
        }
      }

      this.renderer.render(this.scene, this.camera) // 渲染场景
    },

    // 页面初始化入口
    initPage () {
      this.initScene()
      this.initRenderer()
      this.initCamera()
      this.initLight()
      this.initFloor()
      this.initFactory()
      this.initAgv()
      this.initBox()
      this.initAgvBox()
      this.initControl()
      this.initAnimate()
    }
  }
}
</script>

<style scoped>
#container {
  position: absolute;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
</style>